package com.qxl.forest.core.shiro;

import com.qxl.forest.common.constants.factory.ConstantFactory;
import com.qxl.forest.common.constants.state.UserStatus;
import com.qxl.forest.business.persistence.dao.MenuDao;
import com.qxl.forest.business.persistence.dao.RoleDao;
import com.qxl.forest.business.persistence.dao.UserDao;
import com.qxl.forest.business.persistence.entity.Role;
import com.qxl.forest.business.persistence.entity.ShiroUser;
import com.qxl.forest.business.persistence.entity.User;
import com.qxl.forest.common.util.ToolUtil;
import com.qxl.forest.util.Convert;
import org.apache.shiro.authc.CredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: qiuxinlin
 * @Dercription:
 * @Date: 10:13 2017/11/24
 */
@Service
@Transactional(readOnly = true)//如果应用只需要查询，不需要修改，那么read-only缓存将使用，这是最简单、最理想的性能策略
public class ShiroFactroy implements IShiro {

    @Autowired
    UserDao userDao;
    @Autowired
    ConstantFactory constantFactory;
    @Autowired
    MenuDao menuDao;
    @Autowired
    RoleDao roleDao;

    @Override
    public User user(String account) {
        User user = userDao.findByAccount(account);
        //账号不存在
        if (null == user) {
            throw new CredentialsException();
        }
        //账号冻结
        if (user.getStatus() != UserStatus.OK.getCode()) {
            throw new LockedAccountException();
        }
        return user;
    }

    @Override
    public ShiroUser shiroUser(User user) {
        ShiroUser shiroUser = new ShiroUser();
        shiroUser.setId(user.getId());
        shiroUser.setAccount(user.getAccount());
        shiroUser.setDeptId(user.getDeptid());
        shiroUser.setDeptName(constantFactory.getDeptName(user.getDeptid()));
        shiroUser.setName(user.getName());
        Integer[] roleArray = Convert.toIntArray(user.getRoleid());// 角色集合
        List<Integer> roleList = new ArrayList<Integer>();
        List<String> roleNameList = new ArrayList<String>();
        for (int roleId : roleArray) {
            roleList.add(roleId);
            roleNameList.add(constantFactory.getSingleRoleName(roleId));
        }
        shiroUser.setRoleList(roleList);
        shiroUser.setRoleNames(roleNameList);
        return shiroUser;
    }

    @Override
    public List<String> findPermissionsByRoleId(Integer roleId) {
        return menuDao.getResUrlsByRoleId(roleId);
    }

    @Override
    public String findRoleNameByRoleId(Integer roleId) {
        if (0 == roleId) {
            return "--";
        }
        Role role = roleDao.findOne(roleId);
        if (ToolUtil.isNotEmpty(role) && ToolUtil.isNotEmpty(role.getName())) {
            return role.getCode();
        }
        return "";
    }

    @Override
    public SimpleAuthenticationInfo info(ShiroUser shiroUser, User user, String realmName) {
        String credentials = user.getPassword();
        // 密码加盐处理
        String source = user.getSalt();
        ByteSource credentialsSalt = new Md5Hash(source);
        return new SimpleAuthenticationInfo(shiroUser, credentials, credentialsSalt, realmName);
    }
}
